package com.lumlord.util;

import com.lumlord.exception.BusinessException;

import com.lumlord.model.message.MessageDomain;
import com.lumlord.model.message.WebSocketDomain;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.io.IOException;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Web Socket 核心处理类
 * @author GPF
 */
@Slf4j
public abstract class WebSocketHelper   {




    //设置会话信息
    public void openSession(Session session, String id,String group){
        this.setSession(session);

        this.setId(id);
        this.setGroup(group);

        webSocketSet.add(this);
        addOnlineCount();           //在线数加1
    }

    //设置会话信息
    public void closeSession(){
        webSocketSet.remove(this);
        subOnlineCount();           //在线数减1
        log.info("会话 ["+this.id+"] 关闭！当前在线人数为" + getOnlineCount());
    }



    /**
     * 消息发送
     * @param userPorject 用户或项目ID  ,分割 0，用户ID，1，表示 项目ID
     * @param  isProject true 表示 项目ID false 表示 用户ID 匹配 仅当 userPorject 为true 可以
     * @param message 消息内容
     */
    @SneakyThrows
    public int sendUserProject(String userPorject, String message, Boolean isProject){
        boolean isSendAll = (null==userPorject||userPorject.equals("0"));
        Iterator<WebSocketHelper> iterator =  webSocketSet.iterator();
        int sendCount = 0;

        while (iterator.hasNext()){
            WebSocketHelper helper = iterator.next();

            if(isSendAll){
                sendCount++;
                send(helper,message);
            }else if(userPorject.indexOf(",")!=-1){
                String up[] = userPorject.split(",");
                String userId = up[0],projectId = up[1];
                if(helper.getGroup().equals(projectId)&&helper.getId().equals(userId)){
                    sendCount++;
                    send(helper,message);
                }
            }else if(isProject){
                if(helper.getGroup().equals(userPorject)){
                    sendCount++;
                    send(helper,message);
                }
            }else if(!isProject){
                if(helper.getId().equals(userPorject)){
                    sendCount++;
                    send(helper,message);
                }
            }
        }
        return  sendCount;
    }

    @SneakyThrows
    private void send(WebSocketHelper helper, String message){
        Session session = helper.getSession();
        synchronized(session){
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 消息发送给所有人
     * @param messsage
     */
    public int sendAll(String messsage){
      return   sendUserProject(null,messsage,null);
    }


    /**
     *  发送消息实体
     * @param message   Message
     * @throws BusinessException
     */
    public boolean sendInfo(MessageDomain message) throws BusinessException {
        boolean isSendAll = message.getSubscribes().size()==0?true:false;
        Iterator<WebSocketHelper> iterator =  webSocketSet.iterator();
        while (iterator.hasNext()){
            WebSocketHelper helper = iterator.next();
            boolean isSend = isSendAll|| message.getSubscribes().contains(helper.id);
            if(isSend){
                try {
                    helper.getSession().getBasicRemote().sendText(GsonTools.toJson(message));
                } catch (IOException e) {
                    throw new BusinessException(e.getMessage());
                }
            }
        }
        return  true;
    }






    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineCount = new AtomicInteger();
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    // private static ConcurrentHashMap<Integer,WebSocketServerController> userSocketMap = new ConcurrentHashMap<Integer,WebSocketServerController>();
    private static CopyOnWriteArraySet<WebSocketHelper> webSocketSet = new CopyOnWriteArraySet<WebSocketHelper>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
     //接收sid
    private String id ;



    //接受项目ID
    private String group ;




    public static synchronized int getOnlineCount() {
        return onlineCount.get();
    }

    public static synchronized void addOnlineCount() {
        onlineCount.incrementAndGet();
    }

    public static synchronized void subOnlineCount() {
        onlineCount.decrementAndGet();
    }


    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof WebSocketHelper){
            WebSocketHelper wsc = (WebSocketHelper) obj;
            return this.id.equals(wsc.id);
        }else{
            return false;
        }
     }


}
